package com.mes.handler.plan;

import com.basis.utils.HibernateDao;
import com.basis.utils.StringUtil;
import com.mes.data.*;
import com.mes.plan.data.*;
import com.wms.entity.WmsSalesOrder;
import com.wms.entity.WmsSalesOrderDetail;
import com.wms.entity.WmsSalesOrderFoot;
import com.wms.entity.WmsSalesOrderInfo;
import org.apache.log4j.Logger;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.openbravo.base.exception.OBException;
import org.openbravo.client.kernel.BaseActionHandler;
import org.openbravo.dal.service.OBDal;
import org.openbravo.dal.service.OBQuery;
import org.openbravo.database.SessionInfo;
import org.openbravo.model.ad.access.User;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 销售订单审核
 * @author ZT
 */
public class SaleOrderAuditHandler extends BaseActionHandler {
	private Logger logger = Logger.getLogger(this.getClass());
	private boolean createDiyProcess = false;

	@Override
	protected JSONObject execute(Map<String, Object> parameters, String data) {
		JSONObject jsonRep = new JSONObject();
		try {
			JSONObject jsonData = new JSONObject(data);
			String []ids = jsonData.getString("ids").split(",");
			User user = OBDal.getInstance().get(User.class, SessionInfo.getUserId());

			WmsSalesOrder order = null;
			for(String id : ids) {
				order = OBDal.getInstance().get(WmsSalesOrder.class, id);
				if (!"CREATE".equalsIgnoreCase(order.getStatus())) {
					jsonRep.put("result", false);
					jsonRep.put("msg", "销售订单[" + order.getCode() + "]非创建状态不能重复确认！");
					OBDal.getInstance().rollbackAndClose();
					return jsonRep;
				}

				order.setStatus("AUDIT");
				order.setAuditUser(user.getName());
				order.setAuditTime(new Date());

				OBDal.getInstance().save(order);

				cratePlanOrder(order);
			}
			jsonRep.put("result", true);
			jsonRep.put("msg", "下发成功！");
			OBDal.getInstance().commitAndClose();
		} catch (Exception e) {
			e.printStackTrace();
			OBDal.getInstance().rollbackAndClose();
			logger.error("销售订单下发失败：", e);
			try {
				jsonRep.put("result", false);
				jsonRep.put("msg", "下发失败！");
			} catch (JSONException e1) {
			}
			throw new OBException(e);
		}
		return jsonRep;
	}

	/**
	 * 确认通过有创建计划订单
	 */
	private void cratePlanOrder(WmsSalesOrder order) {
		List<WmsSalesOrderDetail> list = order.getWmsSalesOrderDetailList();
		if (list == null || list.isEmpty()) {
			throw new RuntimeException("此销售订单下无列表信息，不能进行确认！");
		}
		EmespPlanOrder plan = null;

		for (WmsSalesOrderDetail detail : list) {
			plan = new EmespPlanOrder();
			plan.setCode(order.getCode() + "-" + detail.getRowNo());
			plan.setWmsSalesOrderDetail(detail);
			plan.setStatus("CREATE");
			plan.setDescription(detail.getDescription());
			plan.setProduct(detail.getProduct());
			plan.setQty(detail.getQty());
			plan.setQtyDone(0l);
			plan.setQtySplit(0l);
			plan.setReqDate(order.getSalesDate());
			plan.setSource(order.getSource());

			OBDal.getInstance().save(plan);

			createPlanOrderFoot(detail, plan);
			createOrderProcess(plan);
		}
	}

	/**
	 * 创建左右脚
	 * @param detail
	 * @param plan
	 */
	private void createPlanOrderFoot(WmsSalesOrderDetail detail, EmespPlanOrder plan) {
		List<WmsSalesOrderFoot> list = detail.getWmsSalesOrderFootList();
		EmespPlanOrderFoot pf = null;

		for (WmsSalesOrderFoot foot : list) {
			pf = new EmespPlanOrderFoot();
			pf.setType(foot.getType());
			pf.setFootWidth(foot.getFootWidth());
			pf.setFootHeight(foot.getFootHeight());
			pf.setFootLength(foot.getFootLength());
			pf.setEmesSize(foot.getEmesSize());
			pf.setDescription(foot.getDescription());
			pf.setXuantouType(foot.getXuantouType());
			pf.setEmespPlanorder(plan);

			OBDal.getInstance().save(pf);

			createPlanOrderBom(foot, pf);
		}
	}

	/**
	 * 创建左右脚
	 * @param foot
	 * @param pf
	 */
	private void createPlanOrderBom(WmsSalesOrderFoot foot, EmespPlanOrderFoot pf) {
		List<WmsSalesOrderInfo> list = foot.getWmsSalesOrderInfoList();
		List<EmesPBomItem> bomItems = null;
		EmespPlanOrderBom bom = null;
		EmesComponent component = null;
		EmesPBomItem bomItem = null;
		Map<String, String> componentMap = new HashMap();//记录已生成的部位BOM，可能还有必须部位物料，不在可选项中
		String productId = foot.getWmsSalesOrderDetail().getProduct().getId();

		for (WmsSalesOrderInfo info : list) {
			componentMap.put(info.getCode(), info.getCode());
			component = getComponent(info.getCode());
			bomItem = getPBomItem(info.getSelectCode());
			if (bomItem != null) {
				bomItems = getBomProduct(bomItem.getId());//一个选项下可能存在多个物料

				//将可选项下物料加入BOM物料清单中
				for (EmesPBomItem item : bomItems) {
					bom = new EmespPlanOrderBom();
					bom.setEmespPlanorderFoot(pf);
					bom.setWmsSalesOrderInfo(info);
					bom.setEmesComponent(component);
					bom.setProduct(item.getProduct());
					bom.setUom(item.getProduct().getUOM());
					bom.setEmesColor(info.getEmesColor());
					bom.setEmesShape(getShape(info.getShapeCode()));
					bom.setDescription(info.getDescription());
					bom.setQty(getSizeQty(item, foot.getEmesSize().getId(), foot.getType()));//物料用量
					bom.setColorCode(info.getColorCode());
					bom.setComponentCode(info.getCode());
					bom.setShapeCode(info.getShapeCode());

					OBDal.getInstance().save(bom);
				}
			}

			//创建DIV信息
			createOrderDiy(info, pf, component);

			//根据部位下直属物料添加到BOM清单中
			bomItems = getComponentProduct(component.getId(), productId);//一个选项下可能存在多个物料

			if (bomItems != null) {
				//将可选项下物料加入BOM物料清单中
				for (EmesPBomItem item : bomItems) {
					bom = new EmespPlanOrderBom();
					bom.setEmespPlanorderFoot(pf);
					bom.setWmsSalesOrderInfo(info);
					bom.setEmesComponent(component);
					bom.setProduct(item.getProduct());
					bom.setUom(item.getProduct().getUOM());
					bom.setEmesColor(info.getEmesColor());
					bom.setEmesShape(getShape(info.getShapeCode()));
					bom.setDescription(info.getDescription());
					bom.setQty(getSizeQty(item, foot.getEmesSize().getId(), foot.getType()));//物料用量
					bom.setColorCode(info.getColorCode());
					bom.setComponentCode(info.getCode());
					bom.setShapeCode(info.getShapeCode());

					OBDal.getInstance().save(bom);
				}
			}
		}

		//检索未在定制项中部位物料
		List<EmesPBomItem> allComponent = getProductAllComponent(productId);
		//将可选项下物料加入BOM物料清单中
		for (EmesPBomItem comp : allComponent) {
			if (componentMap.containsKey(comp.getEmesComponent().getCode())) {
				continue;
			}
			bomItems = getBomProduct(comp.getId());//一个选项下可能存在多个物料

			for (EmesPBomItem item : bomItems) {
				bom = new EmespPlanOrderBom();
				bom.setEmespPlanorderFoot(pf);
				bom.setEmesComponent(comp.getEmesComponent());
				bom.setProduct(item.getProduct());
				bom.setUom(item.getProduct().getUOM());
				bom.setQty(getSizeQty(item, foot.getEmesSize().getId(), foot.getType()));//物料用量
				bom.setEmesColor(comp.getEmesColor());

				OBDal.getInstance().save(bom);
			}
		}
	}

	/**
	 * 生成工单工艺路线
	 */
	private void createOrderProcess(EmespPlanOrder plan) {
		List<EmesProcess> list = getProcessList(plan.getProduct().getId());
		if (list == null || list.isEmpty()) {
			throw new RuntimeException(plan.getProduct().getSearchKey() + "未设置工艺路线！");
		}
		EmespPlanOrderProcess process;
		for (EmesProcess pro : list) {
			if (!createDiyProcess && pro.getName().toUpperCase().indexOf("DIY") > -1) {
				continue;
			}
			//此次应该增加验证
			process = new EmespPlanOrderProcess();
			process.setEmespPlanorder(plan);
			process.setEmesProcess(pro);

			OBDal.getInstance().save(process);
		}
	}
	/**
	 * 生成工单DIY信息
	 */
	private void createOrderDiy(WmsSalesOrderInfo info, EmespPlanOrderFoot pf, EmesComponent component) {
		EmespPlanOrderDiy diy = null;
		if (!StringUtil.isEmpty(info.getFontText()) || info.getIconPath() != null) {
			diy = new EmespPlanOrderDiy();
			diy.setEmesColor(info.getEmesColor());
			diy.setEmesComponent(component);
			diy.setEmespPlanorderFoot(pf);
			diy.setDescription(info.getDescription());

			if (!StringUtil.isEmpty(info.getFontText())) {
				diy.setEmesFont(getFont(info.getFontCode()));
				diy.setFontText(info.getFontText());
				diy.setType("FONT");
			} else {
				diy.setPicPath(info.getPicPath());
				diy.setIconPath(info.getIconPath());
				diy.setType("PIC");
			}
			createDiyProcess = true;//记录已创建了DIY信息
			OBDal.getInstance().save(diy);
		}
	}

	/**
	 * 根据部位编码获取部位对象
	 * @param code
	 * @return
	 */
	private EmesComponent getComponent(String code) {
		if (StringUtil.isEmpty(code)) {
			throw new RuntimeException("部位编码为空");
		}
		OBQuery<EmesComponent> query = OBDal.getInstance().createQuery(EmesComponent.class, "code = :code");
		query.setNamedParameter("code", code);
		return query.uniqueResult();
	}

	/**
	 * 根据可选项BOM项
	 * @param code
	 * @return
	 */
	private EmesPBomItem getPBomItem(String code) {
		if (StringUtil.isEmpty(code)) {
			return null;
		}
		OBQuery<EmesPBomItem> query = OBDal.getInstance().createQuery(EmesPBomItem.class, "level = 'KXX' and code = :code");
		query.setNamedParameter("code", code);
		return query.uniqueResult();
	}

	/**
	 * 根据部位查询未在可选项中物料信息
	 * @param componentId
	 * @return
	 */
	private List<EmesPBomItem> getComponentProduct(String componentId, String productId) {
		OBQuery<EmesPBomItem> query = OBDal.getInstance().createQuery(EmesPBomItem.class,
				"emesPbom.product.id = :productId and level = 'BW' and emesComponent.id = :componentId");
		query.setNamedParameter("productId", productId);
		query.setNamedParameter("componentId", componentId);
		EmesPBomItem bomItem = query.uniqueResult();
		if (bomItem == null) {
			return null;
		}
		return getBomProduct(bomItem.getId());
	}
	/**
	 * 根据选项编码获取对应物料信息
	 * @param bomItemId
	 * @return
	 */
	private List<EmesPBomItem> getBomProduct(String bomItemId) {
		OBQuery<EmesPBomItem> query = OBDal.getInstance().createQuery(EmesPBomItem.class, "level = 'WL' and parent_Id = :pId");
		query.setNamedParameter("pId", bomItemId);
		return query.list();
	}
	/**
	 * 获取尺码用量
	 */
	private BigDecimal getSizeQty(EmesPBomItem bomItem, String sizeId, String type) {
		String sql = "select qty, qty_one from emes_pbom_item_mete where emes_size_id = ? and emes_pbom_item_id = ?";
		Map<String, Object> map = HibernateDao.queryUnique(sql, sizeId, bomItem.getId());
		if (map != null) {
			if ("LEFT".equalsIgnoreCase(type) || "RIGHT".equalsIgnoreCase(type)) {
				return new BigDecimal(map.get("qty_one").toString());
			}
			return new BigDecimal(map.get("qty").toString());
		}
		throw new RuntimeException(bomItem.getProduct().getName() + "未设置此尺码用量！");
	}
	/**
	 * 获取形状
	 */
	private EmesShape getShape(String code) {
		if (StringUtil.isEmpty(code)) {
			return null;
		}
		OBQuery<EmesShape> query = OBDal.getInstance().createQuery(EmesShape.class, "code = :code");
		query.setNamedParameter("code", code);
		return query.uniqueResult();
	}
	/**
	 * 获取形状
	 */
	private EmesFont getFont(String code) {
		if (StringUtil.isEmpty(code)) {
			return null;
		}
		OBQuery<EmesFont> query = OBDal.getInstance().createQuery(EmesFont.class, "code = :code");
		query.setNamedParameter("code", code);
		return query.uniqueResult();
	}
	/**
	 * 获取形体的所有部位信息
	 */
	private List<EmesPBomItem> getProductAllComponent(String productId) {
		OBQuery<EmesPBomItem> query = OBDal.getInstance().createQuery(EmesPBomItem.class,
				"emesPbom.product.id = :productId and level = 'BW'");
		query.setNamedParameter("productId", productId);
		return query.list();
	}
	/**
	 * 获取产品工艺路线
	 * @param productId
	 * @return
	 */
	private List<EmesProcess> getProcessList(String productId) {
		OBQuery<EmesProcess> query = OBDal.getInstance().createQuery(EmesProcess.class,
				"emesProcessRoute.product.id = :productId and active = true");
		query.setNamedParameter("productId", productId);
		return query.list();
	}
}